import { ModalFormData } from "@minecraft/server-ui";
import { system } from "@minecraft/server";

export default class ModalUI {
    /**
     * 玩家对象
     * @type {import("@minecraft/server").Player}
     */
    __player

    /**
     * 表单实例
     * @type {import("@minecraft/server-ui").ModalFormData}
     */
    __form

    /**
     * 表单标题
     * @type {string}
     */
    __title = "未定义"

    /**
     * 表单组件列表
     * @type {Array<FormComponent>}
     */
    __components = []

    /**
     * 玩家繁忙时重复触发的间隔(单位: gametick)
     * @type {number}
     */
    __busy_wait = 1

    /**
     * @param {import("@minecraft/server").Player} player
     */
    constructor(player) {
        this.__player = player;
        this.__form = new ModalFormData();
    }

    /**
     * 设置表单标题
     * @param {string} title
     * @returns {ModalFormUI}
     */
    title(title) {
        this.__title = title;
        return this;
    }

    /**
     * 添加开关组件
     * @param {string} id 组件ID
     * @param {string} text 显示文本
     * @param {boolean} [value=false] 默认值
     * @returns {ModalFormUI}
     */
    addToggle(id, text, value = false) {
        this.__components.push({
            type: "toggle",
            id: id,
            text: text,
            value: value
        });
        return this;
    }

    /**
     * 添加输入框组件
     * @param {string} id 组件ID
     * @param {string} text 显示文本
     * @param {string} [placeholder=""] 占位文本
     * @param {string} [value=""] 默认值
     * @returns {ModalFormUI}
     */
    addInput(id, text, placeholder = "", value = "") {
        this.__components.push({
            type: "input",
            id: id,
            text: text,
            placeholder: placeholder,
            value: value
        });
        return this;
    }

    /**
     * 添加范围滑块组件
     * @param {string} id 组件ID
     * @param {string} text 显示文本
     * @param {number} min 最小值
     * @param {number} max 最大值
     * @param {number} [step=1] 步长
     * @param {number} [value=0] 默认值
     * @returns {ModalFormUI}
     */
    addRange(id, text, min, max, step = 1, value = 0) {
        step = Math.max(1, step);
        value = Math.max(min, Math.min(value, max));

        this.__components.push({
            type: "range",
            id: id,
            text: text,
            min: min,
            max: max,
            step: step,
            value: value
        });
        return this;
    }

    /**
     * 添加选项下拉框
     * @param {string} id 组件ID
     * @param {string} text 显示文本
     * @param {Array<string>} options 选项列表
     * @param {number} [index=0] 默认选项索引
     * @returns {ModalFormUI}
     */
    addOptions(id, text, options, index = 0) {
        this.__components.push({
            type: "options",
            id: id,
            text: text,
            options: options,
            index: index
        });
        return this;
    }

    /**
     * 设置选项映射
     * @param {Array<any>} matchArray 映射数组
     * @returns {ModalFormUI}
     */
    setOptionsMatch(matchArray) {
        if (Array.isArray(matchArray) && this.__components.length > 0) {
            const lastComponent = this.__components[this.__components.length - 1];
            if (lastComponent.type === "options") {
                lastComponent.match = matchArray;
            }
        }
        return this;
    }

    /**
     * 显示表单
     * @param {Function} callback 表单提交回调
     */
    show(callback) {
        // 设置标题
        this.__form.title(this.__title);

        // 添加组件
        for (const comp of this.__components) {
            switch (comp.type) {
                case "toggle":
                    this.__form.toggle(comp.text, { defaultValue: comp.value });
                    break;

                case "input":
                    this.__form.textField(comp.text, comp.placeholder, { defaultValue: comp.value });
                    break;

                case "range":
                    this.__form.slider(
                        comp.text,
                        comp.min,
                        comp.max,
                        { step: comp.step, defaultValue: comp.value }
                    );
                    break;

                case "options":
                    this.__form.dropdown(
                        comp.text,
                        comp.options,
                        { defaultIndex: comp.index }
                    );
                    break;
            }
        }

        // 显示表单并处理回调
        this.__displayForm(callback);
    }

    /**
     * 内部表单显示方法
     * @param {Function} callback 
     */
    __displayForm(callback) {
        this.__form.show(this.__player).then(result => {
            if (result.canceled) {
                if (result.cancelationReason === "UserClosed") {
                    this.__player.sendMessage('菜单已取消')
                } else {
                    system.runTimeout(() => this.__displayForm(callback), this.__busy_wait);
                }
            } else {
                // 处理表单结果
                const formData = {};
                const values = result.formValues;

                for (let i = 0; i < this.__components.length; i++) {
                    const comp = this.__components[i];
                    let value = values[i];

                    // 处理特殊组件类型
                    if (comp.type === "options" && comp.match) {
                        if (Array.isArray(comp.match)) {
                            value = comp.match[value] !== undefined
                                ? comp.match[value]
                                : value;
                        }
                    }

                    // 确保范围值有效
                    if (comp.type === "range") {
                        value = Math.max(comp.min, Math.min(value, comp.max));
                    }

                    // 收集数据
                    if (formData[comp.id] === undefined) {
                        formData[comp.id] = value;
                    } else {
                        formData[comp.id] = Array.isArray(formData[comp.id])
                            ? [...formData[comp.id], value]
                            : [formData[comp.id], value];
                    }
                }

                // 调用回调
                callback(formData);
            }
        });
    }
}

/** @typedef {ToggleComponent | InputComponent | RangeComponent | OptionsComponent} FormComponent */

/** @typedef {{
 *  type: "toggle",
 *  id: string,
 *  text: string,
 *  value: boolean
 * }} ToggleComponent */

/** @typedef {{
 *  type: "input",
 *  id: string,
 *  text: string,
 *  placeholder: string,
 *  value: string
 * }} InputComponent */

/** @typedef {{
 *  type: "range",
 *  id: string,
 *  text: string,
 *  min: number,
 *  max: number,
 *  step: number,
 *  value: number
 * }} RangeComponent */

/** @typedef {{
 *  type: "options",
 *  id: string,
 *  text: string,
 *  options: Array<string>,
 *  index: number,
 *  match?: Array<any>
 * }} OptionsComponent */